package VMM;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import Exceptions.BadFileEx;
import Exceptions.FrameOverflowEx;
import Exceptions.OffsetEx;
import Exceptions.PageOverflowEx;

/**
 * Parser class used to read in addresses from file
 * 
 * @author allanwatson xvb09137
 * @changelog 19/2/12 Moved methods from VMM to here.
 */
public class Parser {
	private BufferedReader fileInput;
	private VMM vm;
	ArrayList arr;// testing purposes only.

	public Parser(String filename, VMM m) {

		vm = m;
		arr = new ArrayList();// array used by tester.
		try {
			fileInput = new BufferedReader(new FileReader(filename));
		} catch (FileNotFoundException e) {
			System.out.println("Files missing: Backing Storage or InputFile");
		}
	}

	public Parser(String filename) {
		arr = new ArrayList();
		try {
			fileInput = new BufferedReader(new FileReader(filename));
		} catch (FileNotFoundException e) {
			System.out.println("Files missing: Backing Storage or InputFile");
		}
	}

	/**
	 * Reads in the addresses, finds value in memory and prints details
	 */
	public void readValues() throws IOException, BadFileEx, FrameOverflowEx {

		for (Object addr : arr) {
			try {
				vm.addressTranslate((Integer.parseInt((String) addr))); // addr
																		// trans
				vm.printLineDetails(); // print details of address
			} catch (NumberFormatException e) {
				error("Line not parsed, expected integer received: " + addr);
			} catch (PageOverflowEx e) {
				error("Page number exceeds page table size");
			} catch (OffsetEx e) {
				error("Offset exceeds frame/page size");
			}
		}

		vm.printRates(); // print fault and hit rates
	}

	public void readAddresses() throws IOException {

		String addr = fileInput.readLine();// read in first line

		while (addr != null) {
			arr.add(addr);
			addr = fileInput.readLine(); // read next address
		}
	}

	/**
	 * Method for printing errors
	 */
	private void error(String str) {
		System.out.println("Error: " + str);
	}

	/**
	 * Method for returning arrayList of addresses, testing only
	 */
	public ArrayList getArray() {
		return arr;
	}

}
